home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload Trio 2 / Shareware Overload Trio Volume 2 (Chestnut CD-ROM).ISO / dir42 / gnudbm14.zip / TESTGDBM.C < prev    next >
C/C++ Source or Header  |  1990-08-24  |  17KB  |  619 lines

  1. /* testgdbm.c - Driver program to test the database routines and to
  2.    help debug gdbm.  Uses inside information to show "system" information */
  3.  
  4. /*  This file is part of GDBM, the GNU data base manager, by Philip A. Nelson.
  5.     Copyright (C) 1990  Free Software Foundation, Inc.
  6.  
  7.     GDBM is free software; you can redistribute it and/or modify
  8.     it under the terms of the GNU General Public License as published by
  9.     the Free Software Foundation; either version 1, or (at your option)
  10.     any later version.
  11.  
  12.     GDBM is distributed in the hope that it will be useful,
  13.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.     GNU General Public License for more details.
  16.  
  17.     You should have received a copy of the GNU General Public License
  18.     along with GDBM; see the file COPYING.  If not, write to
  19.     the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  
  21.     You may contact the author by:
  22.        e-mail:  phil@wwu.edu
  23.       us-mail:  Philip A. Nelson
  24.                 Computer Science Department
  25.                 Western Washington University
  26.                 Bellingham, WA 98226
  27.         phone:  (206) 676-3035
  28.        
  29. *************************************************************************/
  30.  
  31. /*
  32.  * MS-DOS port (c) 1990 by Thorsten Ohl, td12@@ddagsi3.bitnet
  33.  *
  34.  * To this port, the same copying conditions apply as to the
  35.  * original release.
  36.  *
  37.  * IMPORTANT:
  38.  * This file is not identical to the original GNU release!
  39.  * You should have received this code as patch to the official
  40.  * GNU release.
  41.  *
  42.  * MORE IMPORTANT:
  43.  * This port comes with ABSOLUTELY NO WARRANTY.
  44.  *
  45.  * $Header: e:/gnu/gdbm/RCS/testgdbm.c'v 1.4.0.2 90/08/16 09:55:48 tho Exp $
  46.  */
  47.  
  48. #include <stdio.h>
  49. #include <sys/types.h>
  50. #ifndef MSDOS
  51. #include <sys/file.h>
  52. #endif /* not MSDOS */
  53. #include <sys/stat.h>
  54. #include "gdbmdefs.h"
  55. #include "systems.h"
  56. #include "gdbmerrno.h"
  57. #include "extern.h"
  58.  
  59. extern gdbm_error gdbm_errno;
  60.  
  61. extern char * gdbm_version;
  62.  
  63. gdbm_file_info *gdbm_file;
  64.  
  65. #ifdef __STDC__
  66. static void print_bucket (hash_bucket *bucket, char *mesg);
  67. static void _gdbm_print_avail_list (gdbm_file_info *dbf);
  68. extern void main (int argc, char **argv);
  69. void gdbm_perror (char *msg);
  70. #endif /* __STDC__ */
  71.  
  72.  
  73. /* access GDBM_ERRNO.  [tho]  */
  74.  
  75. void
  76. gdbm_perror (char *msg)
  77. {
  78.   char *err_msg;
  79.  
  80.   switch (gdbm_errno)
  81.     {
  82.     case GDBM_NO_ERROR:
  83.       err_msg = "no error";
  84.       break;
  85.     case GDBM_MALLOC_ERROR:
  86.       err_msg = "can't malloc";
  87.       break;
  88.     case GDBM_BLOCK_SIZE_ERROR:
  89.       err_msg = "bad block size";
  90.       break;
  91.     case GDBM_FILE_OPEN_ERROR:
  92.       err_msg = "can't open file";
  93.       break;
  94.     case GDBM_FILE_WRITE_ERROR:
  95.       err_msg = "can't write file";
  96.       break;
  97.     case GDBM_FILE_SEEK_ERROR:
  98.       err_msg = "can't seek file";
  99.       break;
  100.     case GDBM_FILE_READ_ERROR:
  101.       err_msg = "can't read file";
  102.       break;
  103.     case GDBM_BAD_MAGIC_NUMBER:
  104.       err_msg = "bad magic number";
  105.       break;
  106.     case GDBM_EMPTY_DATABASE:
  107.       err_msg = "empty database";
  108.       break;
  109.     case GDBM_CANT_BE_READER:
  110.       err_msg = "can't be reader";
  111.       break;
  112.     case GDBM_CANT_BE_WRITER:
  113.       err_msg = "can't be writer";
  114.       break;
  115.     case GDBM_READER_CANT_DELETE:
  116.       err_msg = "can't delete";
  117.       break;
  118.     case GDBM_READER_CANT_STORE:
  119.       err_msg = "can't store";
  120.       break;
  121.     case GDBM_READER_CANT_REORGANIZE:
  122.       err_msg = "can't reorganize";
  123.       break;
  124.     case GDBM_UNKNOWN_UPDATE:
  125.       err_msg = "unkown update";
  126.       break;
  127.     case GDBM_ITEM_NOT_FOUND:
  128.       err_msg = "item not found";
  129.       break;
  130.     case GDBM_REORGANIZE_FAILED:
  131.       err_msg = "reorganization failed";
  132.       break;
  133.     case GDBM_CANNOT_REPLACE:
  134.       err_msg = "can't replace";
  135.       break;
  136.     default:
  137.       err_msg = "unknown error";
  138.     }
  139.  
  140.   fprintf (stderr, "%s (GDBM error: %s)\n", msg, err_msg);
  141. }
  142.  
  143.  
  144. /* Debug procedure to print the contents of the current hash bucket. */
  145. VOID
  146. print_bucket (bucket, mesg)
  147.      hash_bucket *bucket;
  148.      char *mesg;
  149. {
  150.   int  index;
  151.  
  152.   printf ("******* %s **********\n\nbits = %d\ncount= %d\nHash Table:\n",
  153.      mesg, bucket->bucket_bits, bucket->count);
  154.   printf ("     #    hash value     key size    data size     data adr  home\n");
  155.   for (index = 0; index < gdbm_file->header->bucket_elems; index++)
  156. #ifdef MSDOS
  157.     printf ("  %4d  %12lx  %11d  %11d  %11ld %5d\n", index,
  158.        bucket->h_table[index].hash_value,
  159.        bucket->h_table[index].key_size,
  160.        bucket->h_table[index].data_size,
  161.        bucket->h_table[index].data_pointer,
  162.        (int) (bucket->h_table[index].hash_value % gdbm_file->header->bucket_elems));
  163. #else /* not MSDOS */
  164.     printf ("  %4d  %12x  %11d  %11d  %11d %5d\n", index,
  165.        bucket->h_table[index].hash_value,
  166.        bucket->h_table[index].key_size,
  167.        bucket->h_table[index].data_size,
  168.        bucket->h_table[index].data_pointer,
  169.        bucket->h_table[index].hash_value % gdbm_file->header->bucket_elems);
  170. #endif /* not MSDOS */
  171.  
  172.   printf ("\nAvail count = %1d\n", bucket->av_count);
  173.   printf ("Avail  adr     size\n");
  174.   for (index = 0; index < bucket->av_count; index++)
  175. #ifdef MSDOS
  176.     printf ("%9ld%9d\n", bucket->bucket_avail[index].av_adr,
  177. #else /* not MSDOS */
  178.     printf ("%9d%9d\n", bucket->bucket_avail[index].av_adr,
  179. #endif /* not MSDOS */
  180.                     bucket->bucket_avail[index].av_size);
  181. }
  182.  
  183.  
  184. VOID
  185. _gdbm_print_avail_list (dbf)
  186.      gdbm_file_info *dbf;
  187. {
  188.   LONG temp;
  189.   int size;
  190.   avail_block *av_stk;
  191.  
  192.   /* Print the the header avail block.  */
  193.   printf ("\nheader block\nsize  = %d\ncount = %d\n",
  194.       dbf->header->avail.size, dbf->header->avail.count);
  195.   for (temp = 0; temp < dbf->header->avail.count; temp++)
  196.     {
  197. #ifdef MSDOS
  198.       printf ("  %15d   %10ld \n", dbf->header->avail.av_table[temp].av_size,
  199. #else /* not MSDOS */
  200.       printf ("  %15d   %10d \n", dbf->header->avail.av_table[temp].av_size,
  201. #endif /* not MSDOS */
  202.           dbf->header->avail.av_table[temp].av_adr);
  203.     }
  204.  
  205.   /* Initialize the variables for a pass throught the avail stack. */
  206.   temp = dbf->header->avail.next_block;
  207.   size = ( ( (dbf->header->avail.size * sizeof (avail_elem)) >> 1)
  208.       + sizeof (avail_block));
  209.   av_stk = (avail_block *) alloca (size);
  210. #ifdef MSDOS
  211.   if (av_stk == (avail_block *) 0)
  212.     {
  213.       fprintf (stderr, "alloca failed.\n");
  214.       exit (-2);
  215.     }
  216. #endif /* MSDOS */
  217.  
  218.   /* Print the stack. */
  219.   while (FALSE)
  220.     {
  221.       lseek (dbf->desc, temp, L_SET);
  222. #ifdef MSDOS
  223.       read  (dbf->desc, (char *) av_stk, size);
  224. #else /* not MSDOS */
  225.       read  (dbf->desc, av_stk, size);
  226. #endif /* not MSDOS */
  227.  
  228.       /* Print the block! */
  229.       printf ("\nblock = %d\nsize  = %d\ncount = %d\n", temp,
  230.           av_stk->size, av_stk->count);
  231.       for (temp = 0; temp < av_stk->count; temp++)
  232.     {
  233. #ifdef MSDOS
  234.       printf ("  %15d   %10ld \n", av_stk->av_table[temp].av_size,
  235. #else /* not MSDOS */
  236.       printf ("  %15d   %10d \n", av_stk->av_table[temp].av_size,
  237. #endif /* not MSDOS */
  238.         av_stk->av_table[temp].av_adr);
  239.     }
  240.       temp = av_stk->next_block;
  241.     }
  242. }
  243.  
  244. _gdbm_print_bucket_cache (dbf)
  245.      gdbm_file_info *dbf;
  246. {
  247.   int index;
  248.   char changed;
  249.  
  250.   printf ("Bucket Cache:\n  Index:  Address  Changed  Data_Hash \n");
  251.   for (index=0; index < CACHE_SIZE; index++)
  252.     {
  253.       changed = dbf->bucket_cache[index].ca_changed;
  254. #ifdef MSDOS
  255.       printf ("  %5d:  %7ld  %7s  %lx\n",
  256. #else /* not MSDOS */
  257.       printf ("  %5d:  %7d  %7s  %x\n",
  258. #endif /* not MSDOS */
  259.           index,
  260.           dbf->bucket_cache[index].ca_adr,
  261.           (changed ? "True" : "False"),
  262.           dbf->bucket_cache[index].ca_data.hash_val);
  263.     }
  264. }
  265.  
  266.  
  267. /* The test program allows one to call all the routines plus the hash function.
  268.    The commands are single letter commands.  The user is prompted for all other
  269.    information.  See the help command (?) for a list of all commands. */
  270.  
  271. VOID
  272. main (argc, argv)
  273.      int argc;
  274.      char *argv[];
  275.  
  276. {
  277.  
  278.   char  cmd_ch;
  279.  
  280.   datum key_data;
  281.   datum data_data;
  282.   datum return_data;
  283.  
  284.   char key_line[500];
  285.   char data_line[1000];
  286.  
  287.   char done = FALSE;
  288.  
  289.   char *file_name;
  290.  
  291.  
  292.   /* Argument checking. */
  293.   if (argc > 2)
  294.     {
  295.       printf ("Usage: %s [gdbm-file] \n",argv[0]);
  296.       exit (2);
  297.     }
  298.  
  299.   if (argc > 1)
  300.     {
  301.       file_name = argv[1];
  302.     }
  303.   else
  304.     {
  305.       file_name = "junk.gdbm";
  306.     }
  307.  
  308.   /* Initialize variables. */
  309.   key_data.dptr = NULL;
  310.   data_data.dptr = data_line;
  311.  
  312.   gdbm_file = gdbm_open (file_name, 512, GDBM_WRCREAT, 00664, NULL);
  313.   if (gdbm_file == NULL)
  314.     {
  315.       gdbm_perror ("gdbm_open failed");
  316.       exit (2);
  317.     }
  318.  
  319.   /* Welcome message. */
  320.   printf ("\nWelcome to the gdbm test program.  Type ? for help.\n\n");
  321.   
  322.   while (!done)
  323.     {
  324.       printf ("com -> ");
  325. #ifdef MSDOS            /* shut up the compiler */
  326.       cmd_ch = (char) getchar ();
  327. #else /* not MSDOS */
  328.       cmd_ch = getchar ();
  329. #endif /* not MSDOS */
  330.       if (cmd_ch != '\n')
  331.     {
  332.       char temp;
  333.       do
  334. #ifdef MSDOS            /* shut up the compiler */
  335.           temp = (char) getchar ();
  336. #else /* not MSDOS */
  337.           temp = getchar ();
  338. #endif /* not MSDOS */
  339.       while (temp != '\n' && temp != EOF);
  340.     }
  341.       if (cmd_ch == EOF) cmd_ch = 'q';
  342.       switch (cmd_ch)
  343.     {
  344.     
  345.     /* Standard cases found in all test{dbm,ndbm,gdbm} programs. */
  346.     case '\n':
  347.       printf ("\n");
  348.       break;
  349.  
  350.     case 'c':
  351.       {
  352.         int temp;
  353.         temp = 0;
  354.         if (key_data.dptr != NULL) free (key_data.dptr);
  355.         return_data = gdbm_firstkey (gdbm_file);
  356.         while (return_data.dptr != NULL)
  357.           {
  358.         temp++;
  359.         key_data = return_data;
  360.         return_data = gdbm_nextkey (gdbm_file, key_data);
  361.         free (key_data.dptr);
  362.           }
  363.         printf ("There are %d items in the database.\n\n", temp);
  364.       }
  365.       break;
  366.  
  367.     case 'd':
  368.       if (key_data.dptr != NULL) free (key_data.dptr);
  369.       printf ("key -> ");
  370.       gets (key_line);
  371.       key_data.dptr = key_line;
  372.       key_data.dsize = strlen (key_line)+1;
  373.       if (gdbm_delete (gdbm_file, key_data) != 0)
  374.         gdbm_perror ("Item not found or deleted");
  375.       printf ("\n");
  376.       key_data.dptr = NULL;
  377.       break;
  378.  
  379.     case 'f':
  380.       if (key_data.dptr != NULL) free (key_data.dptr);
  381.       printf ("key -> ");
  382.       gets (key_line);
  383.       key_data.dptr = key_line;
  384.       key_data.dsize = strlen (key_line)+1;
  385.       return_data = gdbm_fetch (gdbm_file, key_data);
  386.       if (return_data.dptr != NULL)
  387.         {
  388.           printf ("data is ->%s\n\n", return_data.dptr);
  389.           free (return_data.dptr);
  390.         }
  391.       else
  392.         printf ("No such item found.\n\n");
  393.       key_data.dptr = NULL;
  394.       break;
  395.  
  396.     case 'n':
  397.       if (key_data.dptr != NULL) free (key_data.dptr);
  398.       printf ("key -> ");
  399.       gets (key_line);
  400.       key_data.dptr = key_line;
  401.       key_data.dsize = strlen (key_line)+1;
  402.       return_data = gdbm_nextkey (gdbm_file, key_data);
  403.       if (return_data.dptr != NULL)
  404.         {
  405.           key_data = return_data;
  406.           printf ("key is  ->%s\n", key_data.dptr);
  407.           return_data = gdbm_fetch (gdbm_file, key_data);
  408.           printf ("data is ->%s\n\n", return_data.dptr);
  409.           free (return_data.dptr);
  410.         }
  411.       else
  412.         {
  413.           gdbm_perror ("No such item found");
  414.           key_data.dptr = NULL;
  415.         }
  416.       break;
  417.  
  418.     case 'q':
  419.       done = TRUE;
  420.       break;
  421.  
  422.     case 's':
  423.       if (key_data.dptr != NULL) free (key_data.dptr);
  424.       printf ("key -> ");
  425.       gets (key_line);
  426.       key_data.dptr = key_line;
  427.       key_data.dsize = strlen (key_line)+1;
  428.       printf ("data -> ");
  429.       gets (data_line);
  430.       data_data.dsize = strlen (data_line)+1;
  431.       if (gdbm_store (gdbm_file, key_data, data_data, GDBM_REPLACE) != 0)
  432.         gdbm_perror ("Item not inserted");
  433.       printf ("\n");
  434.       key_data.dptr = NULL;
  435.       break;
  436.  
  437.     case '1':
  438.       if (key_data.dptr != NULL) free (key_data.dptr);
  439.       key_data = gdbm_firstkey (gdbm_file);
  440.       if (key_data.dptr != NULL)
  441.         {
  442.           printf ("key is  ->%s\n", key_data.dptr);
  443.           return_data = gdbm_fetch (gdbm_file, key_data);
  444.           printf ("data is ->%s\n\n", return_data.dptr);
  445.           free (return_data.dptr);
  446.         }
  447.       else
  448.         gdbm_perror ("No such item found");
  449.       break;
  450.  
  451.     case '2':
  452.       return_data = gdbm_nextkey (gdbm_file, key_data);
  453.       if (return_data.dptr != NULL)
  454.         {
  455.           free (key_data.dptr);
  456.           key_data = return_data;
  457.           printf ("key is  ->%s\n", key_data.dptr);
  458.           return_data = gdbm_fetch (gdbm_file, key_data);
  459.           printf ("data is ->%s\n\n", return_data.dptr);
  460.           free (return_data.dptr);
  461.         }
  462.       else
  463.         gdbm_perror ("No such item found");
  464.       break;
  465.  
  466.  
  467.     /* Special cases for the testgdbm program. */
  468.     case 'r':
  469.       {
  470.         if (gdbm_reorganize (gdbm_file))
  471.           gdbm_perror ("Reorganization failed");
  472.         else
  473.           printf ("Reorganization succeeded. \n\n");
  474.       }
  475.       break;
  476.  
  477.     case 'A':
  478.       _gdbm_print_avail_list (gdbm_file);
  479.       printf ("\n");
  480.       break;
  481.  
  482.     case 'B':
  483.       {
  484.         int temp;
  485.         char number[80];
  486.  
  487.         printf ("bucket? ");
  488.         gets (number);
  489.         sscanf (number,"%d",&temp);
  490.  
  491.         if (temp >= gdbm_file->header->dir_size /4)
  492.           {
  493.         gdbm_perror ("Not a bucket");
  494.         break;
  495.           }
  496.         _gdbm_get_bucket (gdbm_file, temp);
  497.       }
  498.       printf ("Your bucket is now ");
  499.  
  500.     case 'C':
  501.       print_bucket (gdbm_file->bucket, "Current bucket");
  502.       printf ("\n current directory entry = %d.\n", gdbm_file->bucket_dir);
  503. #ifdef MSDOS
  504.       printf (" current bucket address  = %ld.\n\n",
  505. #else /* not MSDOS */
  506.       printf (" current bucket address  = %d.\n\n",
  507. #endif /* not MSDOS */
  508.           gdbm_file->cache_entry->ca_adr);
  509.       break;
  510.  
  511.     case 'D':
  512.       printf ("Hash table directory.\n");
  513.       printf ("  Size =  %d.  Bits = %d. \n\n",gdbm_file->header->dir_size,
  514.           gdbm_file->header->dir_bits);
  515.       {
  516.         int temp;
  517.  
  518.         for (temp = 0; temp < gdbm_file->header->dir_size / 4; temp++)
  519.           {
  520. #ifdef MSDOS
  521.         printf ("  %10d:  %12ld\n", temp, gdbm_file->dir[temp]);
  522. #else /* not MSDOS */
  523.         printf ("  %10d:  %12d\n", temp, gdbm_file->dir[temp]);
  524. #endif /* not MSDOS */
  525.         if ( (temp+1) % 20 == 0 && isatty (0))
  526.           {
  527.             printf ("*** CR to continue: ");
  528.             while (getchar () != '\n') /* Do nothing. */;
  529.           }
  530.           }
  531.       }
  532.       printf ("\n");
  533.       break;
  534.  
  535.     case 'F':
  536.       {
  537. #ifndef MSDOS            /* shut up the compiler */
  538.           int temp;
  539. #endif /* not MSDOS */
  540.  
  541.         printf ("\nFile Header: \n\n");
  542. #ifdef MSDOS
  543.         printf ("  table        = %ld\n", gdbm_file->header->dir);
  544. #else /* not MSDOS */
  545.         printf ("  table        = %d\n", gdbm_file->header->dir);
  546. #endif /* not MSDOS */
  547.         printf ("  table size   = %d\n", gdbm_file->header->dir_size);
  548.         printf ("  table bits   = %d\n", gdbm_file->header->dir_bits);
  549.         printf ("  block size   = %d\n", gdbm_file->header->block_size);
  550.         printf ("  bucket elems = %d\n", gdbm_file->header->bucket_elems);
  551.         printf ("  bucket size  = %d\n", gdbm_file->header->bucket_size);
  552. #ifdef MSDOS
  553.         printf ("  header magic = %lx\n", gdbm_file->header->header_magic);
  554. #else /* not MSDOS */
  555.         printf ("  header magic = %x\n", gdbm_file->header->header_magic);
  556. #endif /* not MSDOS */
  557.         printf ("  next block   = %d\n", gdbm_file->header->next_block);
  558.         printf ("  avail size   = %d\n", gdbm_file->header->avail.size);
  559.         printf ("  avail count  = %d\n", gdbm_file->header->avail.count);
  560.         printf ("  avail nx blk = %d\n", gdbm_file->header->avail.next_block);
  561.         printf ("\n");
  562.       }
  563.       break;
  564.  
  565.         case 'H':
  566.       if (key_data.dptr != NULL) free (key_data.dptr);
  567.       printf ("key -> ");
  568.       gets (key_line);
  569.       key_data.dptr = key_line;
  570.       key_data.dsize = strlen (key_line)+1;
  571. #ifdef MSDOS
  572.       printf ("hash value = %lx. \n\n", _gdbm_hash (key_data));
  573. #else /* not MSDOS */
  574.       printf ("hash value = %x. \n\n", _gdbm_hash (key_data));
  575. #endif /* not MSDOS */
  576.       key_data.dptr = NULL;
  577.       break;
  578.  
  579.     case 'K':
  580.       _gdbm_print_bucket_cache (gdbm_file);
  581.       break;
  582.  
  583.     case 'V':
  584.       printf ("%s\n\n", gdbm_version);
  585.       break;
  586.  
  587.     case '?':
  588.       printf ("c - count (number of entries)\n");
  589.       printf ("d - delete\n");
  590.       printf ("f - fetch\n");
  591.       printf ("n - nextkey\n");
  592.       printf ("q - quit\n");
  593.       printf ("s - store\n");
  594.       printf ("1 - firstkey\n");
  595.       printf ("2 - nextkey on last key (from n, 1 or 2)\n\n");
  596.  
  597.       printf ("r - reorganize\n");
  598.       printf ("A - print avail list\n");
  599.       printf ("B - get and print current bucket n\n");
  600.       printf ("C - print current bucket\n");
  601.       printf ("D - print hash directory\n");
  602.       printf ("F - print file header\n");
  603.       printf ("H - hash value of key\n");
  604.       printf ("K - print the bucket cache\n");
  605.       printf ("V - print version of gdbm\n");
  606.       break;
  607.  
  608.     default:
  609.       printf ("What? \n\n");
  610.       break;
  611.  
  612.     }
  613.     }
  614.  
  615.   /* Quit normally. */
  616.   exit (0);
  617.  
  618. }
  619.